package com.dream.service;


import com.dream.common.utils.JsonUtils;
import com.dream.common.utils.payutils.bean.MessageBeanOld;
import com.dream.dto.socket.SocketBean;
import com.dream.entity.GroupMember;
import com.dream.entity.NextSendContinueBean;
import com.dream.entity.RemindNextSenderBean;
import com.dream.net.socket.base.SocketController;
import com.dream.service.basic.AsyncInvokeService;
import com.dream.service.basic.BaseServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Component
public class DelayRelayQueue {

    private final Logger LOGGER = LoggerFactory.getLogger(DelayRelayQueue.class);


    @Resource
    private SocketController socketController;
    @Resource
    private AsyncInvokeService asyncInvokeService;

    /**
     * 先入先出：通知队列
     */
    private Map<String, RemindNextSenderBean> remindQueue = new LinkedHashMap<>();

    /**
     * 先入先出：T人队列
     */
    private Map<String, RemindNextSenderBean> kickQueue = new LinkedHashMap<>();

    /**
     * 连续伐包玩家，key是云笔记账号，value是接包连续详情
     */
    public Map<String, NextSendContinueBean> nextSendUserInfoMap = new HashMap();

    /**
     * 重置每个用户的提醒信息（根据username删除之前的，加入新的）
     *
     * @param username
     * @param atNextSenderBean
     * @param kickNextSenderBean
     */
    public void resetQueueByUsername(String username, RemindNextSenderBean atNextSenderBean, RemindNextSenderBean kickNextSenderBean) {
        if (atNextSenderBean != null) {
            atNextSenderBean.expireTime = System.currentTimeMillis() + (atNextSenderBean.nextSendAtTime * 1000);
            remindQueue.put(username, atNextSenderBean);
        }
        if (kickNextSenderBean != null) {
            kickNextSenderBean.expireTime = System.currentTimeMillis() + (kickNextSenderBean.nextSendKickTime * 1000);
            kickQueue.put(username, kickNextSenderBean);
        }
    }


    @Scheduled(initialDelay = 10 * 1000, fixedRate = 3000)
    public void invokeRemindQueue() {
        Iterator<Map.Entry<String, RemindNextSenderBean>> iterator = remindQueue.entrySet().iterator();
        RemindNextSenderBean eachLine;
        Map.Entry<String, RemindNextSenderBean> entry;
        while (iterator.hasNext()) {
            entry = iterator.next();
            if (System.currentTimeMillis() >= entry.getValue().expireTime) {
                eachLine = entry.getValue();
                //socket推送给app
                if (!SocketController.socketUserChannels.containsKey(eachLine.username)) {
                    LOGGER.error("invokeRemindQueue socketUserChannels notFound;    userName:{}", eachLine.username);
                    iterator.remove();
                    continue;
                }
                MessageBeanOld messageBean = new MessageBeanOld();
                messageBean.messageType = 2;
                messageBean.sendMsg = eachLine.nextSendUsername + "\n" + eachLine.nextSendAtTime + "秒内未接包，请接包";
                messageBean.atList = Collections.singletonList(new MessageBeanOld.AtUserInfo(eachLine.nextSendUserId, eachLine.nextSendUsername));
                SocketBean socketBean = SocketBean.buildData(1, JsonUtils.toJSONString(messageBean));
                asyncInvokeService.msgUnityWrite(eachLine.username, socketBean.data);
                socketController.sendCommand(eachLine.username, socketBean);
                iterator.remove();
            } else {
                break;
            }
        }
    }

    /**
     * 3s的调度会造成不够实时,但考虑到同步产生的耗时不会差很大
     * 如果要求实时，则需要把if内代码异步处理,调度间隔1s
     */
    @Scheduled(initialDelay = 10 * 1000, fixedRate = 3000)
    public void invokeKickQueue() {
        Iterator<Map.Entry<String, RemindNextSenderBean>> iterator = kickQueue.entrySet().iterator();
        RemindNextSenderBean eachLine;
        Map.Entry<String, RemindNextSenderBean> entry;
        while (iterator.hasNext()) {
            entry = iterator.next();
            if (System.currentTimeMillis() >= entry.getValue().expireTime) {
                eachLine = entry.getValue();
                //再进行后置处理,避免循环通知
                GroupMember groupMember = new GroupMember();
                groupMember.userName = eachLine.username;
                groupMember.friendId = eachLine.nextSendUserId;
                groupMember = BaseServiceHelper.getGroupMemberMapper().selectOne(groupMember);
                if (groupMember != null && socketController.sendCommand(eachLine.username, SocketBean.buildData(7, JsonUtils.toJSONString(groupMember)))) {
                    BaseServiceHelper.getGroupMemberMapper().deleteByPrimaryKey(groupMember.id);
                }
                iterator.remove();
            } else {
                break;
            }
        }
    }
}
